import {creepConfiguration} from './spawn'

const spawnFunc: Function = function spawnCreeps(creepConfiguration): Function {
  return () => {
    _.pairs(creepConfiguration).forEach(pair => {
      let spawn: string = pair[0];
      if (Game.spawns[spawn].spawning !== null) return;
      let config = pair[1];
      let temp: number;
      let lastFix: string = _.now().toString();
      for (let key in config.numberConfig) {
        console.log(`${key}数目校对中...`);
        let creepName = key;
        if (config.prefix) creepName = `${config.prefix}_${creepName}`;
        if ((temp = _.filter(Game.creeps, creep => creep.memory.role == `${creepName}`).length) < config.numberConfig[key]) {
          const context: Object = {spawn, creepName, config};
          if (creepName in config.judge && !config.judge[creepName](context)) {
            console.log(`试图孵化${creepName},但因前置条件未满足拒绝。`)
            continue;
          }
          console.log(Game.spawns[`${spawn}`].spawnCreep(
            config.unitConfig[key],//组件
            `${creepName}#${lastFix.substring(lastFix.length - 4)}`,//名字
            {memory: {role: `${creepName}`}}
          ), ` 目标为${config.numberConfig[key]}个${creepName},目前有${temp}个${creepName},准备创建一个${creepName}#${temp}`);//角色
          return;
        }
      }
    })

  }
}(creepConfiguration);

function refreshRoomIdTable(roomCode) {
  const structureCache: any = _.groupBy
  (Game.rooms[roomCode]
      .find(FIND_STRUCTURES),
    (structure) => structure.structureType);

  for (const structure in structureCache) {
    structureCache[structure] = structureCache[structure].map(e => e.id)
  }
  structureCache[STRUCTURE_STORAGE] = [Game.rooms[roomCode].storage.id];
  if (!global.roomCache) {
    global.roomCache = {}
  }
  global.roomCache[roomCode] = structureCache;
}

export function refreshCreepConfigMeta() {

}

function calculateCreepNumber() {
  calculateNumber('carrier2');
  calculateNumber('harvester1');
  calculateNumber('harvester2');
}

function calculateNumber(creepType) {
  if (global.creepNumber === undefined)
    global.creepNumber = {};
  if (!global.creepNumber[creepType]) {
    global.creepNumber[creepType] = Object.keys(Game.creeps).filter((name) => name.startsWith(creepType)).length
  }
}

function clearCreepMemory(): void {
  let creepsCopy: { [creepName: string]: Creep } = Object.assign({}, Game.creeps);
  let memoryCreepNames: string[] = Object.keys(Memory.creeps);
  memoryCreepNames.forEach(name => {
    if (!(name in creepsCopy)) {
      delete Memory.creeps[name];
    }
  })
}

function setTimer(tick: number | Function, callback: Function, opt?: any) {

  if (typeof tick === 'function') {
    if (tick()) {
      callback(opt);
    }
  }
  if (typeof tick === 'number') {
    if (Game.time % tick === 0) {
      callback(opt);
    }
  }
}


export {
  spawnFunc as spawnCreeps,
  clearCreepMemory,
  setTimer,
  calculateCreepNumber,
  refreshRoomIdTable
};
